arbitrary cache attributes.
Signed-off-by: Kieran Mansley <kmansley@solarflare.com>
Signed-off-by: Keir Fraser <keir.fraser@eu.citrix.com>
// mfn: frame: machine page frame
// flags: GNTMAP_readonly | GNTMAP_application_map | GNTMAP_contains_pte
int
-create_grant_host_mapping(unsigned long gpaddr,
- unsigned long mfn, unsigned int flags)
+create_grant_host_mapping(unsigned long gpaddr, unsigned long mfn,
+ unsigned int flags, unsigned int cache_flags)
{
struct domain* d = current->domain;
struct page_info* page;
int ret;
- if (flags & (GNTMAP_device_map |
- GNTMAP_application_map | GNTMAP_contains_pte)) {
- gdprintk(XENLOG_INFO, "%s: flags 0x%x\n", __func__, flags);
+ if ((flags & (GNTMAP_device_map |
+ GNTMAP_application_map | GNTMAP_contains_pte)) ||
+ (cache_flags)) {
+ gdprintk(XENLOG_INFO, "%s: flags 0x%x cache_flags 0x%x\n",
+ __func__, flags, cache_flags);
return GNTST_general_error;
}
}
int create_grant_host_mapping(
- unsigned long addr, unsigned long frame, unsigned int flags)
+ unsigned long addr, unsigned long frame, unsigned int flags, unsigned int cache_flags)
{
if (flags & GNTMAP_application_map) {
printk("%s: GNTMAP_application_map not supported\n", __func__);
BUG();
return GNTST_general_error;
}
+ if (cache_flags) {
+ printk("%s: cache_flags not supported\n", __func__);
+ BUG();
+ return GNTST_general_error;
+ }
return create_grant_va_mapping(addr, frame, current);
}
return 0;
}
- /* No reference counting for out-of-range I/O pages. */
- if ( !mfn_valid(mfn) )
- return 1;
-
- d = dom_io;
+ return 1;
}
/* Foreign mappings into guests in shadow external mode don't
mfn, get_gpfn_from_mfn(mfn),
l1e_get_intpte(l1e), d->domain_id);
}
- else if ( (pte_flags_to_cacheattr(l1f) !=
- ((page->count_info >> PGC_cacheattr_base) & 7)) &&
- !is_iomem_page(mfn) )
+ else if ( pte_flags_to_cacheattr(l1f) !=
+ ((page->count_info >> PGC_cacheattr_base) & 7) )
{
uint32_t x, nx, y = page->count_info;
uint32_t cacheattr = pte_flags_to_cacheattr(l1f);
void put_page_from_l1e(l1_pgentry_t l1e, struct domain *d)
{
- unsigned long pfn = l1e_get_pfn(l1e);
- struct page_info *page = mfn_to_page(pfn);
- struct domain *e;
- struct vcpu *v;
+ unsigned long pfn = l1e_get_pfn(l1e);
+ struct page_info *page;
+ struct domain *e;
+ struct vcpu *v;
- if ( !(l1e_get_flags(l1e) & _PAGE_PRESENT) || !mfn_valid(pfn) )
+ if ( !(l1e_get_flags(l1e) & _PAGE_PRESENT) || is_iomem_page(pfn) )
return;
+ page = mfn_to_page(pfn);
+
e = page_get_owner(page);
/*
return replace_grant_va_mapping(addr, frame, l1e_empty(), v);
}
-int create_grant_host_mapping(
- uint64_t addr, unsigned long frame, unsigned int flags)
+int create_grant_host_mapping(uint64_t addr, unsigned long frame,
+ unsigned int flags, unsigned int cache_flags)
{
l1_pgentry_t pte = l1e_from_pfn(frame, GRANT_PTE_FLAGS);
if ( !(flags & GNTMAP_readonly) )
l1e_add_flags(pte,_PAGE_RW);
+ l1e_add_flags(pte, cacheattr_to_pte_flags(cache_flags >> 5));
+
if ( flags & GNTMAP_contains_pte )
return create_grant_pte_mapping(addr, pte, current);
return create_grant_va_mapping(addr, pte, current);
int handle;
unsigned long frame = 0;
int rc = GNTST_okay;
+ unsigned int cache_flags;
struct active_grant_entry *act;
struct grant_mapping *mt;
grant_entry_t *sha;
frame = act->frame;
+ cache_flags = (sha->flags & (GTF_PAT | GTF_PWT | GTF_PCD) );
+
spin_unlock(&rd->grant_table->lock);
- if ( unlikely(!mfn_valid(frame)) ||
- unlikely(!((op->flags & GNTMAP_readonly) ?
- get_page(mfn_to_page(frame), rd) :
- get_page_and_type(mfn_to_page(frame), rd,
- PGT_writable_page))) )
+ if ( is_iomem_page(frame) )
{
- if ( !rd->is_dying )
- gdprintk(XENLOG_WARNING, "Could not pin grant frame %lx\n", frame);
- rc = GNTST_general_error;
- goto undo_out;
+ if ( !iomem_access_permitted(rd, frame, frame) )
+ {
+ gdprintk(XENLOG_WARNING,
+ "Iomem mapping not permitted %lx (domain %d)\n",
+ frame, rd->domain_id);
+ rc = GNTST_general_error;
+ goto undo_out;
+ }
+
+ rc = create_grant_host_mapping(
+ op->host_addr, frame, op->flags, cache_flags);
+ if ( rc != GNTST_okay )
+ goto undo_out;
}
-
- if ( op->flags & GNTMAP_host_map )
+ else
{
- rc = create_grant_host_mapping(op->host_addr, frame, op->flags);
- if ( rc != GNTST_okay )
+ if ( unlikely(!mfn_valid(frame)) ||
+ unlikely(!((op->flags & GNTMAP_readonly) ?
+ get_page(mfn_to_page(frame), rd) :
+ get_page_and_type(mfn_to_page(frame), rd,
+ PGT_writable_page))) )
{
- if ( !(op->flags & GNTMAP_readonly) )
- put_page_type(mfn_to_page(frame));
- put_page(mfn_to_page(frame));
+ if ( !rd->is_dying )
+ gdprintk(XENLOG_WARNING, "Could not pin grant frame %lx\n",
+ frame);
+ rc = GNTST_general_error;
goto undo_out;
}
-
- if ( op->flags & GNTMAP_device_map )
+
+ if ( op->flags & GNTMAP_host_map )
{
- (void)get_page(mfn_to_page(frame), rd);
- if ( !(op->flags & GNTMAP_readonly) )
- get_page_type(mfn_to_page(frame), PGT_writable_page);
+ rc = create_grant_host_mapping(op->host_addr, frame, op->flags, 0);
+ if ( rc != GNTST_okay )
+ {
+ if ( !(op->flags & GNTMAP_readonly) )
+ put_page_type(mfn_to_page(frame));
+ put_page(mfn_to_page(frame));
+ goto undo_out;
+ }
+
+ if ( op->flags & GNTMAP_device_map )
+ {
+ (void)get_page(mfn_to_page(frame), rd);
+ if ( !(op->flags & GNTMAP_readonly) )
+ get_page_type(mfn_to_page(frame), PGT_writable_page);
+ }
}
}
if ( op->flags & GNTMAP_device_map )
{
- if ( op->flags & GNTMAP_readonly )
- put_page(mfn_to_page(op->frame));
- else
- put_page_and_type(mfn_to_page(op->frame));
+ if ( !is_iomem_page(act->frame) )
+ {
+ if ( op->flags & GNTMAP_readonly )
+ put_page(mfn_to_page(op->frame));
+ else
+ put_page_and_type(mfn_to_page(op->frame));
+ }
}
if ( (op->host_addr != 0) && (op->flags & GNTMAP_host_map) )
goto unmap_out;
}
- if ( op->flags & GNTMAP_readonly )
+ if ( !is_iomem_page(op->frame) )
+ {
+ if ( !(op->flags & GNTMAP_readonly) )
+ put_page_type(mfn_to_page(op->frame));
put_page(mfn_to_page(op->frame));
- else
- put_page_and_type(mfn_to_page(op->frame));
+ }
}
if ( (op->map->flags & (GNTMAP_device_map|GNTMAP_host_map)) == 0 )
{
BUG_ON(!(act->pin & GNTPIN_devr_mask));
act->pin -= GNTPIN_devr_inc;
- put_page(mfn_to_page(act->frame));
+ if ( !is_iomem_page(act->frame) )
+ put_page(mfn_to_page(act->frame));
}
if ( map->flags & GNTMAP_host_map )
{
BUG_ON(!(act->pin & GNTPIN_hstr_mask));
act->pin -= GNTPIN_hstr_inc;
- gnttab_release_put_page(mfn_to_page(act->frame));
+ if ( !is_iomem_page(act->frame) )
+ gnttab_release_put_page(mfn_to_page(act->frame));
}
}
else
{
BUG_ON(!(act->pin & GNTPIN_devw_mask));
act->pin -= GNTPIN_devw_inc;
- put_page_and_type(mfn_to_page(act->frame));
+ if ( !is_iomem_page(act->frame) )
+ put_page_and_type(mfn_to_page(act->frame));
}
if ( map->flags & GNTMAP_host_map )
{
BUG_ON(!(act->pin & GNTPIN_hstw_mask));
act->pin -= GNTPIN_hstw_inc;
- gnttab_release_put_page_and_type(mfn_to_page(act->frame));
+ if ( !is_iomem_page(act->frame) )
+ gnttab_release_put_page_and_type(mfn_to_page(act->frame));
}
if ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0 )
#define INITIAL_NR_GRANT_FRAMES 1
// for grant map/unmap
-int create_grant_host_mapping(unsigned long gpaddr, unsigned long mfn, unsigned int flags);
+int create_grant_host_mapping(unsigned long gpaddr, unsigned long mfn,
+ unsigned int flags, unsigned int cache_flags);
int replace_grant_host_mapping(unsigned long gpaddr, unsigned long mfn, unsigned long new_gpaddr, unsigned int flags);
// for grant transfer
extern long pte_remove(ulong flags, ulong ptex, ulong avpn,
ulong *hi, ulong *lo);
-int create_grant_host_mapping(
- unsigned long addr, unsigned long frame, unsigned int flags);
+int create_grant_host_mapping(unsigned long addr, unsigned long frame,
+ unsigned int flags, unsigned int cache_flags);
int replace_grant_host_mapping(
unsigned long addr, unsigned long frame, unsigned long new_addr,
unsigned int flags);
* Caller must own caller's BIGLOCK, is responsible for flushing the TLB, and
* must hold a reference to the page.
*/
-int create_grant_host_mapping(
- uint64_t addr, unsigned long frame, unsigned int flags);
+int create_grant_host_mapping(uint64_t addr, unsigned long frame,
+ unsigned int flags, unsigned int cache_flags);
int replace_grant_host_mapping(
uint64_t addr, unsigned long frame, uint64_t new_addr, unsigned int flags);
* GTF_readonly: Restrict @domid to read-only mappings and accesses. [GST]
* GTF_reading: Grant entry is currently mapped for reading by @domid. [XEN]
* GTF_writing: Grant entry is currently mapped for writing by @domid. [XEN]
+ * GTF_PAT, GTF_PWT, GTF_PCD: (x86) cache attribute flags for the grant [GST]
*/
#define _GTF_readonly (2)
#define GTF_readonly (1U<<_GTF_readonly)
#define GTF_reading (1U<<_GTF_reading)
#define _GTF_writing (4)
#define GTF_writing (1U<<_GTF_writing)
+#define _GTF_PWT (5)
+#define GTF_PWT (1U<<_GTF_PWT)
+#define _GTF_PCD (6)
+#define GTF_PCD (1U<<_GTF_PCD)
+#define _GTF_PAT (7)
+#define GTF_PAT (1U<<_GTF_PAT)
/*
* Subflags for GTF_accept_transfer: